import { BASE_URL, TIME_OUT, SUCCESS_CODE } from '../config'
import axios from 'axios'
import type { AxiosInstance, AxiosResponse } from 'axios'
import { errorHandler, headerHandler } from './handler'

export class Request {
  private instance: AxiosInstance
  constructor() {
    this.instance = axios.create({
      baseURL: BASE_URL,
      timeout: TIME_OUT,
    })
    this.setInterceptors()
  }

  private setInterceptors() {
    this.instance.interceptors.request.use(headerHandler)
    this.instance.interceptors.response.use(
      (res: AxiosResponse) => {
        /**
         * 文件流 单处处理，不做统一配置
         */
        // @ts-expect-error 忽略文件类型检查
        if (res.config.isFile) {
          return res
        }
        /**
         * 后台参考格式
         * code:500 | 200,
         * message:"请求失败 | 请求成功",
         */
        if (res.status === 200 && res.data.code === SUCCESS_CODE) {
          return res.data
        } else {
          const errData = {
            code: res.data.code,
            message: res.data.message,
          }
          return errorHandler(errData)
        }
      },
      (error) => {
        return errorHandler(error)
      }
    )
  }

  get<T>(url: string, options?: object | string) {
    return this.instance<T>({
      url,
      method: 'get',
      params: options,
    })
  }

  post<T>(url: string, options?: object | string) {
    return this.instance<T>({
      url,
      method: 'post',
      data: options,
    })
  }

  put<T>(url: string, options?: object | string) {
    return this.instance<T>({
      url,
      method: 'put',
      data: options,
    })
  }

  delete<T>(url: string, options?: object | string) {
    return this.instance<T>({
      url,
      method: 'delete',
      data: options,
    })
  }

  download<T>(url: string, params?: object | string) {
    // @ts-expect-error download
    return this.instance<T>({
      url,
      method: 'get',
      params,
      responseType: 'blob',
      isFile: true,
    })
  }
}

const request = new Request()

export default request
